﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Common;
using BusinessObjects;
using BusinessLogic;
using DCMS_Framework;
using System.Text.RegularExpressions;
using DCMSExceptions;

namespace Presentation {
  /// <summary>
  /// Settings form
  /// </summary>
  public partial class SettingsForm : Form {

    private UserBll userBll = new UserBll( );
    private ZipcodeBll zipBll = new ZipcodeBll( );
    private SortableBindingList<CityZipcode> zipList;
    private CityZipcode zip;
    private User user;

    #region - Constructor -

    /// <summary>
    /// Initializes a new instance of the <see cref="SettingsForm"/> class.
    /// </summary>
    public SettingsForm( ) {
      InitializeComponent( );
      zip = new CityZipcode( );
      this.openPictureFileDialog.Filter = "jpg files (*.jpg)|*.jpg|png files (*.png)|*.png|bmp files|*.bmp|All files (*.*)|*.*";

    }

    #endregion

    #region - Events -

    private void SettingsForm_Load( object sender, EventArgs e ) {
      zipList = zipBll.GetAllZipcodes( );

      loginNameTextBox.Enabled = SettingsSingleton.Settings.FirstRun;
      passwordTextBox.Enabled = SettingsSingleton.Settings.FirstRun;

      if ( !SettingsSingleton.Settings.FirstRun ) {
        nameTextBox.Text = SettingsSingleton.Settings.CurrentUser.Name;
        firstNameTextBox.Text = SettingsSingleton.Settings.CurrentUser.FirstName;
        loginNameTextBox.Text = SettingsSingleton.Settings.CurrentUser.LoginName;
        passwordTextBox.Text = SettingsSingleton.Settings.CurrentUser.Password;
        autoLogonCheckBox.Checked = SettingsSingleton.Settings.CurrentUser.AutoLogin;
        phoneTextBox.Text = SettingsSingleton.Settings.CurrentUser.Phone;
        gsmTextBox.Text = SettingsSingleton.Settings.CurrentUser.Gsm;
        emergencyPhoneTextBox.Text = SettingsSingleton.Settings.CurrentUser.EmergencyPhone;
        emailTextBox.Text = SettingsSingleton.Settings.CurrentUser.Email;
        nationalNumberTextBox.Text = SettingsSingleton.Settings.CurrentUser.NationalNumber;
        streetTextBox.Text = SettingsSingleton.Settings.CurrentUser.Address.Street;
        zipcodeTextBox.Text = SettingsSingleton.Settings.CurrentUser.Address.Zipcode;
        cityTextBox.Text = SettingsSingleton.Settings.CurrentUser.Address.City;
        startTimeTextBox.Text = SettingsSingleton.Settings.CurrentUser.StartTime;
        stopTimeTextBox.Text = SettingsSingleton.Settings.CurrentUser.StopTime;
        photoPictureBox.Image = SettingsSingleton.Settings.CurrentUser.Photo;
      }

    }

    private void okButton_Click( object sender, EventArgs e ) {
      if ( ValidateChildren( ) ) {
        if ( SettingsSingleton.Settings.FirstRun ) {
          
          SaveUser( CreateFirstUser( ) );
          SettingsSingleton.Settings.FirstRun = false;
          new AppBll( ).SetAppData( );
          Application.Restart( );
        } else {
          CreateUserSettings( );
          SaveUser( SettingsSingleton.Settings.CurrentUser );
        }
      }
    }

    private void searchZipcodeButton_Click( object sender, EventArgs e ) {
      ZipcodeListForm zipcodeForm = new ZipcodeListForm( );
      if ( zipcodeForm.ShowDialog( ) == DialogResult.OK ) {
        zip = zipcodeForm.Zipcode.Copy( );
        zipcodeTextBox.Text = zipcodeForm.Zipcode.Zipcode;
        cityTextBox.Text = zipcodeForm.Zipcode.City;

      }
    }

    private void zipcodeTextBox_Leave( object sender, EventArgs e ) {
      //bool found = false;      
      if ( !string.IsNullOrEmpty( zipcodeTextBox.Text ) ) {
        foreach ( CityZipcode zipcode in zipList ) {
          if ( zipcode.Zipcode == zipcodeTextBox.Text ) {
            zip = zipcode.Copy( );
            cityTextBox.Text = zip.City;
            //found = true;
            break;
          }
        }
      }
    }

    private void textBox_TextChanged( object sender, EventArgs e ) {
      extendedErrorProvider.SetError( ( TextBox ) sender, "" );
    }

    private void maskTextBox_TextChanged( object sender, EventArgs e ) {
      extendedErrorProvider.SetError( ( MaskedTextBox ) sender, "" );
    }

    private void readIdCardButton_Click( object sender, EventArgs e ) {
      try {
        BasicCardData data = CardReader.ReadCard( );
        if ( data != null ) {
          nameTextBox.Text = data.Name;
          firstNameTextBox.Text = data.FirstName;
          streetTextBox.Text = data.Street;
          zipcodeTextBox.Text = data.Zipcode;
          cityTextBox.Text = data.City;
          bool zipcodeExists = false;
          foreach ( CityZipcode zipcode in zipList ) {
            if ( zipcode.Zipcode == data.Zipcode
              && zipcode.City == data.City
              && zipcode.CountryCode == data.CountryCode ) {
              zipcodeExists = true;
            }
          }
          if ( !zipcodeExists ) {
            CityZipcode zip = new CityZipcode( data.Zipcode, data.City, data.CountryId );
            zip.ZipcodeId = 0;
            zipBll.SaveZipcode( zip );
          }
          photoPictureBox.Image = data.Photo;
          photoPictureBox.Visible = true;
          nationalNumberTextBox.Text = data.NationalNumber;


          if ( SettingsSingleton.Settings.FirstRun ) {
            CreateFirstUser( );
          } else {
            CreateUserSettings( );
          }
        }

      } catch ( be.belgium.eid.BEID_ExNoReader ) {
        MessageBox.Show( "Geen kaartlezer gevonden. \n Controleer of deze goed is aangesloten en probeer opnieuw", "Kaartlezer", MessageBoxButtons.OK, MessageBoxIcon.Exclamation );
      } catch ( be.belgium.eid.BEID_ExNoCardPresent ) {
        MessageBox.Show( "Geen kaart gevonden.", "Kaartlezer", MessageBoxButtons.OK, MessageBoxIcon.Exclamation );
      } catch ( Exception ex ) {
        MessageBox.Show( ex.ToString( ) + "\n" + ex.Message, "Kaartlezer fout", MessageBoxButtons.OK, MessageBoxIcon.Error );
      }

    }

    private void textBox_MouseDown( object sender, MouseEventArgs e ) {
      ( ( MaskedTextBox ) sender ).SelectAll( );
    }

    private void photoButton_Click( object sender, EventArgs e ) {
      if ( openPictureFileDialog.ShowDialog( ) == DialogResult.OK ) {
        Image photo = Image.FromFile( openPictureFileDialog.FileName );
        photoPictureBox.Image = photo;
        if ( SettingsSingleton.Settings.CurrentUser != null ) {
          SettingsSingleton.Settings.CurrentUser.Photo = photo;
        }
      }
    }

    private void pictureCloseButton_Click( object sender, EventArgs e ) {
      if ( MessageBox.Show( "Foto verwijderen?", "", MessageBoxButtons.YesNo, MessageBoxIcon.Question ) == DialogResult.Yes ) {
        if ( SettingsSingleton.Settings.CurrentUser != null ) {
          SettingsSingleton.Settings.CurrentUser.Photo = null;
        }
        photoPictureBox.Image = null;
        pictureCloseButton.Visible = false;
      }
    }

    private void SettingsForm_FormClosing( object sender, FormClosingEventArgs e ) {
      if ( SettingsSingleton.Settings.FirstRun || SettingsSingleton.Settings.CurrentUser == null ) {
        if ( MessageBox.Show( "Je gegevens zijn nog niet bewaard. \nBen je zeker dat je wilt stoppen.", "Persoonlijke gegevens", MessageBoxButtons.YesNo, MessageBoxIcon.Question ) == System.Windows.Forms.DialogResult.No ) {
          e.Cancel = true;
        } else {
          e.Cancel = false;
        }
      }
    }

    #endregion

    private void CreateUserSettings( ) {
      SettingsSingleton.Settings.CurrentUser.Name = nameTextBox.Text;
      SettingsSingleton.Settings.CurrentUser.FirstName = firstNameTextBox.Text;
      SettingsSingleton.Settings.CurrentUser.LoginName = loginNameTextBox.Text;
      SettingsSingleton.Settings.CurrentUser.Password = passwordTextBox.Text;
      SettingsSingleton.Settings.CurrentUser.AutoLogin = autoLogonCheckBox.Checked;
      SettingsSingleton.Settings.CurrentUser.LastActivity = DateTime.Now;
      SettingsSingleton.Settings.CurrentUser.Phone = phoneTextBox.Text;
      SettingsSingleton.Settings.CurrentUser.Photo = photoPictureBox.Image;
      SettingsSingleton.Settings.CurrentUser.Gsm = gsmTextBox.Text;
      SettingsSingleton.Settings.CurrentUser.Email = emailTextBox.Text;
      SettingsSingleton.Settings.CurrentUser.EmergencyPhone = emergencyPhoneTextBox.Text;
      SettingsSingleton.Settings.CurrentUser.NationalNumber = nationalNumberTextBox.Text;
      SettingsSingleton.Settings.CurrentUser.Address.Street = streetTextBox.Text;
      SettingsSingleton.Settings.CurrentUser.Address.City = zip.City;
      SettingsSingleton.Settings.CurrentUser.Address.CountryCode = zip.CountryCode;
      SettingsSingleton.Settings.CurrentUser.Address.CountryId = zip.CountryId;
      SettingsSingleton.Settings.CurrentUser.Address.CountryName = zip.CountryName;
      SettingsSingleton.Settings.CurrentUser.Address.Zipcode = zip.Zipcode;
      SettingsSingleton.Settings.CurrentUser.Address.ZipcodeId = zip.ZipcodeId;
      SettingsSingleton.Settings.CurrentUser.StartTime = startTimeTextBox.Text;
      SettingsSingleton.Settings.CurrentUser.StopTime = stopTimeTextBox.Text;
    }

    private User CreateFirstUser( ) {
      user = new User( );
      user.Name = nameTextBox.Text;
      user.FirstName = firstNameTextBox.Text;
      user.LoginName = loginNameTextBox.Text;
      user.Password = passwordTextBox.Text;
      user.AutoLogin = autoLogonCheckBox.Checked;
      user.LastActivity = DateTime.Now;
      user.Photo = photoPictureBox.Image;
      user.Phone = phoneTextBox.Text;
      user.Gsm = gsmTextBox.Text;
      user.Email = emailTextBox.Text;
      user.EmergencyPhone = emergencyPhoneTextBox.Text;
      user.NationalNumber = nationalNumberTextBox.Text;
      user.Address.Street = streetTextBox.Text;
      user.Address.City = zip.City;
      user.Address.CountryCode = zip.CountryCode;
      user.Address.CountryId = zip.CountryId;
      user.Address.CountryName = zip.CountryName;
      user.Address.Zipcode = zip.Zipcode;
      user.Address.ZipcodeId = zip.ZipcodeId;
      user.StartTime = startTimeTextBox.Text;
      user.StopTime = stopTimeTextBox.Text;
      return user;
    }

    private void SaveUser( User newUser ) {
      try {
        userBll.SaveUser( newUser );
        loginNameTextBox.Enabled = false;
        passwordTextBox.Enabled = false;
        SettingsSingleton.Settings.CurrentUser = newUser;
      } catch ( BusinessException ex ) {
        MessageBox.Show( ex.Message, "Fout bij save", MessageBoxButtons.OK, MessageBoxIcon.Error );
      } catch ( Exception ex ) {
        MessageBox.Show( ex.Message, ex.ToString( ), MessageBoxButtons.OK, MessageBoxIcon.Error );
      }
    }

    #region - Validation -

    private void nameTextBox_Validating( object sender, CancelEventArgs e ) {
      extendedErrorProvider.SetError( nameTextBox, "" );
      if ( string.IsNullOrEmpty( nameTextBox.Text ) ) {
        extendedErrorProvider.SetError( nameTextBox, "Naam verplicht." );
        e.Cancel = true;
      }
    }

    private void loginNameTextBox_Validating( object sender, CancelEventArgs e ) {
      extendedErrorProvider.SetError( loginNameTextBox, "" );
      if ( string.IsNullOrEmpty( loginNameTextBox.Text ) ) {
        extendedErrorProvider.SetError( loginNameTextBox, "Loginnaam verplicht." );
        e.Cancel = true;
      }
    }

    private void passwordTextBox_Validating( object sender, CancelEventArgs e ) {
      extendedErrorProvider.SetError( passwordTextBox, "" );
      if ( string.IsNullOrEmpty( passwordTextBox.Text ) ) {
        extendedErrorProvider.SetError( passwordTextBox, "Paswoord verplicht." );
        e.Cancel = true;
      }
    }

    private void emailTextBox_Validating( object sender, CancelEventArgs e ) {
      extendedErrorProvider.SetError( emailTextBox, "" );
      if ( string.IsNullOrEmpty( emailTextBox.Text ) ) {
        extendedErrorProvider.SetError( emailTextBox, "Email verplicht." );
        e.Cancel = true;
      } else {
        if ( !PresentationHelper.VaildateEmailString( emailTextBox.Text ) ) {
          extendedErrorProvider.SetError( emailTextBox, "Ongeldig email formaat." );
          e.Cancel = true;
        }
      }
    }

    private void emergencyPhoneTextBox_Validating( object sender, CancelEventArgs e ) {
      extendedErrorProvider.SetError( emergencyPhoneTextBox, "" );
      if ( string.IsNullOrEmpty( emergencyPhoneTextBox.Text ) ) {
        extendedErrorProvider.SetError( emergencyPhoneTextBox, "Nood telefoon nummer verplicht." );
        e.Cancel = true;
      }
    }

    private void streetTextBox_Validating( object sender, CancelEventArgs e ) {
      extendedErrorProvider.SetError( streetTextBox, "" );
      if ( string.IsNullOrEmpty( streetTextBox.Text ) ) {
        extendedErrorProvider.SetError( streetTextBox, "Adres verplicht." );
        e.Cancel = true;
      }
    }

    private void startTimeTextBox_Validating( object sender, CancelEventArgs e ) {
      extendedErrorProvider.SetError( startTimeTextBox, "" );
      if ( string.IsNullOrEmpty( startTimeTextBox.Text ) || startTimeTextBox.Text.Trim( ) == ":" ) {
        extendedErrorProvider.SetError( startTimeTextBox, "Start tijd verplicht." );
        e.Cancel = true;
      } else {
        Regex regex = new Regex( "^([0-1][0-9]|[2][0-3]):([0-5][0-9])$" );
        if ( !regex.IsMatch( startTimeTextBox.Text ) ) {
          extendedErrorProvider.SetError( startTimeTextBox, "Ongeldige tijd." );
          e.Cancel = true;
        }
      }
    }

    private void stopTimeTextBox_Validating( object sender, CancelEventArgs e ) {
      extendedErrorProvider.SetError( stopTimeTextBox, "" );
      if ( string.IsNullOrEmpty( stopTimeTextBox.Text ) || stopTimeTextBox.Text.Trim( ) == ":" ) {
        extendedErrorProvider.SetError( stopTimeTextBox, "Stop tijd verplicht." );
        e.Cancel = true;
      } else {
        Regex regex = new Regex( "^([0-1][0-9]|[2][0-3]):([0-5][0-9])$" );
        if ( !regex.IsMatch( stopTimeTextBox.Text ) ) {
          extendedErrorProvider.SetError( stopTimeTextBox, "Ongeldige tijd." );
          e.Cancel = true;
        }
      }

      if ( ( string.IsNullOrEmpty( startTimeTextBox.Text ) || startTimeTextBox.Text.Trim( ) == ":" )
        && !( string.IsNullOrEmpty( stopTimeTextBox.Text ) || stopTimeTextBox.Text.Trim( ) == ":" ) ) {
        extendedErrorProvider.SetError( startTimeTextBox, "Start tijd verplicht." );
        e.Cancel = true;
      } else if ( !( string.IsNullOrEmpty( startTimeTextBox.Text ) || startTimeTextBox.Text.Trim( ) == ":" )
        && ( string.IsNullOrEmpty( stopTimeTextBox.Text ) || stopTimeTextBox.Text.Trim( ) == ":" ) ) {
        extendedErrorProvider.SetError( stopTimeTextBox, "Stop tijd verplicht." );
        e.Cancel = true;
      } else if ( !( string.IsNullOrEmpty( startTimeTextBox.Text ) || startTimeTextBox.Text.Trim( ) == ":" )
        && !( string.IsNullOrEmpty( stopTimeTextBox.Text ) || stopTimeTextBox.Text.Trim( ) == ":" ) ) {
        Regex regex = new Regex( "^([0-1][0-9]|[2][0-3]):([0-5][0-9])$" );
        if ( regex.IsMatch( startTimeTextBox.Text ) && regex.IsMatch( stopTimeTextBox.Text ) ) {
          TimeSpan fromTime = TimeSpan.Parse( startTimeTextBox.Text );
          TimeSpan toTime = TimeSpan.Parse( stopTimeTextBox.Text );
          if ( toTime < fromTime ) {
            extendedErrorProvider.SetError( stopTimeTextBox, "Stop tijd moet groter dan Start tijd zijn." );
            e.Cancel = true;
          }
        }
      }
    }

    private void zipcodeTextBox_Validating( object sender, CancelEventArgs e ) {
      extendedErrorProvider.SetError( zipcodeTextBox, "" );
      if ( string.IsNullOrEmpty( zipcodeTextBox.Text ) ) {
        extendedErrorProvider.SetError( zipcodeTextBox, "Postcode verplicht." );
        e.Cancel = true;
      } else {
        bool found = false;
        foreach ( CityZipcode zipcode in zipList ) {
          if ( zipcode.Zipcode == zipcodeTextBox.Text ) {
            found = true;
          }
        }
        if ( !found ) {
          extendedErrorProvider.SetError( zipcodeTextBox, "Postcode niet geconfigureerd." );
          e.Cancel = true;
        }
      }
    }

    private void control_Validated( object sender, EventArgs e ) {
      extendedErrorProvider.SetError( ( Control ) sender, "" );
    }

    #endregion


  }
}
